package com.feng.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.feng.dao.UserDao;
import com.feng.dto.UserDto;
import com.feng.entity.Permission;
import com.feng.entity.User;
import com.feng.service.ESService;
import com.feng.service.UserService;
import com.feng.util.BeanCopyUtil;
import com.feng.util.CodeEncryptUtil;
import com.feng.util.StringUtil;
import com.feng.vo.PageVo;
import com.feng.vo.ResultVo;
import com.feng.vo.UserAddVo;
import com.feng.vo.UserVo;
import org.elasticsearch.common.collect.CopyOnWriteHashMap;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author: 丰
 * @date: 2022/12/29 14:21
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Autowired
    private ESService<UserDto> esService;

    @Autowired
    RabbitTemplate rabbitTemplate;


    @Override
    public ResultVo<Integer> register(UserVo userVo, HttpServletRequest request) {
        ResultVo<Integer> resultVo = ResultVo.failed();
        // 查询数据库是否存在该用户的信息
        if (!StrUtil.isBlank(userVo.getUsername()) && !StrUtil.isBlank(userVo.getPassword())){
            User user = userDao.findByUsername(userVo.getUsername());
            if (user == null){
                // 不存在，则保存用户信息
                // 先将密码加密
                String newPassword = CodeEncryptUtil.md5(userVo.getPassword());
                // 保存
                User user1 = new User();
                user1.setUsername(userVo.getUsername());
                user1.setPassword(newPassword);
                String date = StringUtil.getStringDate();
                user1.setCreateTime(date);
                user1.setUpdateTime(date);
                user1.setEnable(1);
                int insert = userDao.insert(user1);
                if (insert != 0){
                    // 保存数据到session域
                    request.getSession().setAttribute("user", user1);
                    return ResultVo.success(insert).message("注册成功");
                }
            }
            return resultVo.message("当前用户名已经存在");
        }
        return resultVo.message("注册失败");
    }

    @Override
    public ResultVo<UserDto> login(UserVo userVo, HttpServletRequest request) {
        ResultVo<UserDto> resultVo = ResultVo.failed();
        // 只有非空的时候才有登录流程
        if (!StrUtil.isBlank(userVo.getUsername()) && !StrUtil.isBlank(userVo.getPassword())){
            // 重置密码，将密码加密
            userVo.setPassword(CodeEncryptUtil.md5(userVo.getPassword()));
            // 检查是否账号与密码是否匹配
            User user = userDao.checked(userVo);
            if (user != null){
                // 返回视图对象
                UserDto userDto = new UserDto();
                BeanUtil.copyProperties(user, userDto);
                // 将用户信息交给mq
                // exchange, routingKey, message
                Map<String, String> map = new HashMap<>();
                map.put("username", userDto.getUsername());
                map.put("email", userDto.getEmail());
                rabbitTemplate.convertAndSend("feng.exchanges.topic",
                        "feng.send.email",
                        map);

                // 保存数据到session域
                request.getSession().setAttribute("user", user);
                return ResultVo.success(userDto).message("登录成功");
            }
        }
        return resultVo.message("用户名或密码错误");
    }

    @Override
    public ResultVo<Integer> insert(UserAddVo userAddVo) {
        ResultVo<Integer> resultVo = ResultVo.failed();
        // 查询数据库是否存在该用户的信息
        if (!StrUtil.isBlank(userAddVo.getUsername()) && !StrUtil.isBlank(userAddVo.getPassword())){
            User user = userDao.findByUsername(userAddVo.getUsername());
            if (user == null){
                User user1 = new User();
                // 先将密码加密
                String newPassword = CodeEncryptUtil.md5(userAddVo.getPassword());
                BeanUtil.copyProperties(userAddVo, user1);
                user1.setPassword(newPassword);
                String date = StringUtil.getStringDate();
                user1.setCreateTime(date);
                user1.setUpdateTime(date);
                user1.setEnable(1);
                Integer i = userDao.addUser(user1);
                if (i != 0){
                    return ResultVo.success(i);
                }
            }
            return resultVo.message("当前用户已存在");
        }
        return resultVo;
    }

    @Override
    public ResultVo<Integer> update(UserAddVo userAddVo) {
        userAddVo.setUpdateTime(StringUtil.getStringDate());
        int result = userDao.update(userAddVo);
        if (result == 1){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<Integer> updatePassword(UserVo userVo) {
        ResultVo<Integer> resultVo = ResultVo.failed();
        // 通过拿到数据库中的数据
        User user = userDao.selectById(userVo.getId());
        if (user == null){
            return resultVo.message("当前用户不存在");
        }
        String oldPassword = CodeEncryptUtil.md5(userVo.getOldPassword());
        // 对比密码是否正确
        if (!user.getPassword().equals(oldPassword)){
            return resultVo.message("密码输入有误");
        }
        // 密码加密
        String newPassword = CodeEncryptUtil.md5(userVo.getPassword());
        userVo.setPassword(newPassword);

        // 更新时间
        userVo.setUpdateTime(StringUtil.getStringDate());
        // 更新数据
        int result = userDao.updatePassword(userVo);
        if (result == 1){
            return ResultVo.success(result);
        }
        return resultVo;
    }

    @Override
    public ResultVo<Integer> deleteAll(Integer[] ids) {
        int[] ints = StringUtil.integersToInts(ids);
        int result = userDao.deleteAll(ints);
        if (result > 0){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<Integer> deleteById(int id) {
        int result = userDao.deleteById(id);
        if (result == 1){
            return ResultVo.success(result);
        }
        return ResultVo.failed();
    }

    @Override
    public ResultVo<UserDto> selectById(int id) {
        User user = userDao.selectById(id);
        UserDto userDto = new UserDto();
        BeanUtil.copyProperties(user, userDto);
        return ResultVo.success(userDto);
    }

    @Override
    public ResultVo<List<UserDto>> selectAll(PageVo pageVo) {
        // 如果为空，就设置为null
        StringUtil.checkPageVo(pageVo);
        try {
            return esService.getDoc(pageVo, "user_doc", UserDto.class);
        }catch (Exception e){
            List<User> userList = userDao.selectAll(pageVo);
            List<UserDto> userDtoList = BeanCopyUtil.copyListProperties(userList, UserDto.class);
            ResultVo<List<UserDto>> resultVo = ResultVo.success(userDtoList);
            // 查出count
            resultVo.count(userDao.count(pageVo));
            return resultVo.code(0);
        }
    }

    public List<UserDto> selectAll() {
        // 如果为空，就设置为null
        PageVo pageVo = new PageVo();
        pageVo.setPage(1);
        pageVo.setLimit(10000);
        List<User> userList = userDao.selectAll(pageVo);
        List<UserDto> userDtoList = BeanCopyUtil.copyListProperties(userList, UserDto.class);
        return userDtoList;
    }

    @Override
    public UserDetails userSetAuthentication(String username) {
        // 拿到登录用户
        User userEntity = userDao.findByUsername(username);
        // 拿到用户的权限
        List<Permission> permissions = userDao.getPermissionByUsername(username);
        // 设置权限
        userEntity.setAuthorities(permissions);
        return userEntity;
    }
}
